package baiqitun.stupro.common.workflow.util;

import baiqitun.stupro.common.exception.enums.support.NotFoundExceptionEnum;
import baiqitun.stupro.common.workflow.enums.ProcessVariableEnum;
import baiqitun.stupro.common.exception.support.NotFoundException;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotBlank;
import java.util.HashMap;
import java.util.Map;

/**
 * @author kedaji
 */
@Service
public class RuntimeTaskUtil {
    @Autowired
    private RuntimeUtil runtimeUtil;
    @Autowired
    private TaskUtil taskUtil;

    /**
     * 启动一个流程，此流程会自动创建一个由owner发起的任务，
     * @param processDefinitionKey 流程定义key
     * @param businessId 业务表id
     * @param owner 任务发起人（流程变量）
     * @param assignee 任务处理人（流程变量）
     * @param name 名称（流程变量）
     * @param description 说明（流程变量）
     */
    @Transactional(rollbackFor = Exception.class)
    public void startProcessInstanceWithTask(@NotBlank(message = "流程定义key不能为空") String processDefinitionKey,
                                     String businessId,
                                     String owner, String assignee,
                                     String name, String description){
        // 设置流程变量
        Map<String, Object> variables = new HashMap<>();
        variables.put(ProcessVariableEnum.ASSIGNEE.name(), assignee);
        variables.put(ProcessVariableEnum.NAME.name(), name);
        variables.put(ProcessVariableEnum.DESCRIPTION.name(), description);
        startProcessInstance(processDefinitionKey, businessId, owner,variables);
    }

    @Transactional(rollbackFor = Exception.class)
    public void startProcessInstance(@NotBlank(message = "流程定义key不能为空") String processDefinitionKey,
                                             String businessId, String owner, Map<String, Object> variables){
        // 启动流程
        ProcessInstance processInstance = runtimeUtil.startProcessInstanceByKey(processDefinitionKey, businessId, variables);
        if (variables == null){
            variables = new HashMap<>();
        }
        variables.put(ProcessVariableEnum.OWNER.name(), owner);
        // 获取流程的任务
        Task task = taskUtil.getTaskByProcessInstanceId(processDefinitionKey, processInstance.getId());
        if (task == null){
            throw new NotFoundException(NotFoundExceptionEnum.TASK_NOT_FOUND);
        }
        taskUtil.setOwnerForTask(processDefinitionKey, task.getId(), owner);
    }

    /**
     * 撤回任务并结束流程
     * @param processDefinitionKey 流程定义key
     * @param taskId 任务id
     * @param deleteReason 描述撤回任务的原因
     */
    @Transactional(rollbackFor = Exception.class)
    public void within(@NotBlank(message = "流程定义key不能为空") String processDefinitionKey,
                       String taskId, String deleteReason) {
        Task existedTask = taskUtil.getExistedTask(processDefinitionKey, taskId);
        runtimeUtil.deleteProcessInstance(existedTask.getProcessInstanceId(), deleteReason);
    }
}
